import React from 'react';
import PropTypes from 'prop-types';
import path from 'ramda/es/path';
import { useForm } from 'react-hook-form';
import { gql, useMutation } from '@apollo/client';
import fetch from 'API/fetch'
import { CheckmarkFilled16 as VerifiedIcon } from '@carbon/icons-react';
import Joi from 'joi';
import { joiResolver } from '@hookform/resolvers';

import Dialog from '@kuiper-components/dialog';
import Input from '@kuiper-components/input';
import Button from '@kuiper-components/button';
import Notification from '@kuiper-components/notification';

import { alertReceiver } from '../../../../../../common/validation';
import Form, { Field } from '../../../../../components/Form';
import omitTypename from '../../../../../helpers/omitTypename';
import VerificationCode from './VerificationCode';
import s from './ReceiverEditor.module.css';

const validationSchema = joiResolver(
	Joi.object({
		record: alertReceiver,
		phoneVerificationCode: Joi.string().allow('').pattern(/\d{6}/).messages({
			'any.pattern': '验证为6位数字',
			'string.pattern.base': '验证为6位数字',
		}),
		emailVerificationCode: Joi.string().allow('').pattern(/\d{6}/).messages({
			'any.pattern': '验证为6位数字',
			'string.pattern.base': '验证为6位数字',
		}),
	})
);

export default function ReceiverEditor({
	step: customStep,
	children,
	refetch,
	receiverUpdateOne,
	receiver,
	init,
	nameDisabled,
	alertReceiverBalance,
	emailAutoSend,
	phoneAutoSend,
	...props
}) {
	const [graphqlError, setGraphQLError] = React.useState(null);
	const [dialogVisible, setDialogVisible] = React.useState(false);
	const defaultValues = React.useMemo(
		() => ({
			record: omitTypename(receiver),
			phoneVerificationCode: '',
			emailVerificationCode: '',
		}),
		[receiver]
	);
	const form = useForm({
		defaultValues,
		resolver: validationSchema,
		mode: 'onBlur',
	});
	const formData = form.watch(['record.phone', 'record.email']);
	const email = formData['record.email'];
	const phone = formData['record.phone'];

	const error = path([undefined], form.errors) || graphqlError;

	const emailError = form?.errors?.record?.email || null;
	const phoneError = form?.errors?.record?.phone || null;
	const handleClose = () => {
		setDialogVisible(false);
		refetch && refetch();
		// 关闭弹框时将错误清除
		form.clearErrors();
		setGraphQLError(null);
	};

	const handleSubmit = variables => {
		setGraphQLError(null);
		if (!variables?.record?.name.trim()) {
			setGraphQLError({ message: '请输入告警接收人名称' });
			return;
		}
		if (!variables?.record?.email && !variables?.record?.phone) {
			setGraphQLError({ message: '请填入至少一个联系方式' });
			return;
		}
		const { phoneVerificationCode: phone_code, emailVerificationCode: email_code } = variables
		let fn;
		if (!receiver.receiver_id) {
			fn = fetch('/api/v2/alerts/receiver', { method: 'POST', body: JSON.stringify({...variables.record, phone_code, email_code}) });
		} else {
			fn = fetch('/api/v2/alerts/receiver', {
				method: 'PUT',
				body: JSON.stringify({...variables.record, phone_code, email_code, receiver_id: receiver.receiver_id}),
			});
		}

		fn.then(({ data, code }) => {
			Notification.success({
				placement: 'top',
				message: `告警人${receiver.receiver_id ? '编辑' : '添加'}成功！`,
			});
			refetch && refetch();
			if (code === 200) {
				handleClose();
			}
		}).catch(error => {
			setGraphQLError(error);
		});
	};

	return (
		<>
			{React.cloneElement(children, {
				...children.props,
				onClick(e) {
					if (alertReceiverBalance <= 0) {
						Notification.error({
							message: '已超出最大告警人数，无法继续添加。',
							placement: 'top',
							style: { width: '22rem' },
						});
						return;
					}
					if (children.props.onClick) children.props.onClick(e);
					setDialogVisible(true);
					form && form.reset(defaultValues || {});
				},
			})}
			<Dialog
				visible={dialogVisible}
				destroyOnClose={true}
				title={!init ? '编辑告警人' : '添加告警人'}
				wrapClassName={s.dialog}
				{...props}
				onClose={handleClose}
			>
				<Form className={s.edit} form={form} onSubmit={handleSubmit}>
					<Field
						className={s.field}
						componentClassName={s.component}
						required
						label="姓名"
						name="record.name"
						as={Input}
						placeholder="请输入告警接收人名称"
						disabled={nameDisabled}
					/>
					<Field
						className={s.field}
						componentClassName={s.component}
						label="邮箱"
						name="record.email"
						as={Input}
						after={
							receiver?.email_verified ? (
								<VerifiedIcon className={s.verifiedIcon} />
							) : (
								<span />
							)
						}
						placeholder="请输入邮箱地址"
					/>
					<Field
						name="emailVerificationCode"
						as={VerificationCode}
						className={s.verificationCode}
						type="email"
						autoSend={emailAutoSend}
						btnDisabled={emailError || !email}
						contact={email}
					/>
					<Field
						className={s.field}
						componentClassName={s.component}
						label="手机"
						name="record.phone"
						as={Input}
						after={
							receiver?.phone_verified ? (
								<VerifiedIcon className={s.verifiedIcon} />
							) : (
								<span />
							)
						}
						placeholder="请输入手机号码"
					/>
					<Field
						name="phoneVerificationCode"
						as={VerificationCode}
						className={s.verificationCode}
						type="phone"
						autoSend={phoneAutoSend}
						btnDisabled={phoneError || !phone}
						contact={phone}
					/>
					{error && (
						<div className={s.error}>
							{error.message.replace(/\[.*?\]/g, '')}
						</div>
					)}
					<div className={s.actions}>
						<Button className={s.btn} onClick={handleClose}>
							取消
						</Button>
						<Button primary className={s.btn} type="submit">
							{init ? '添加' : '保存'}
						</Button>
					</div>
				</Form>
			</Dialog>
		</>
	);
}

ReceiverEditor.propTypes = {
	step: PropTypes.oneOf(['edit', 'verify']),
	receiver: PropTypes.shape({
		_id: PropTypes.string,
		name: PropTypes.string,
		phone_verified: PropTypes.string,
		email_verified: PropTypes.string,
	}),
	init: PropTypes.number,
	children: PropTypes.element.isRequired,
	refetch: PropTypes.func,
	receiverUpdateOne: PropTypes.func.isRequired,
	nameDisabled: PropTypes.bool,
	alertReceiverBalance: PropTypes.number,
	emailAutoSend: PropTypes.bool,
	phoneAutoSend: PropTypes.bool,
};

ReceiverEditor.defaultProps = {
	step: 'edit',
	receiver: {},
	nameDisabled: false,
	emailAutoSend: false,
	phoneAutoSend: false,
};
